#include "pch.hpp"
#include "DebuggerConnection.hpp"

using namespace Engine::Edit;




DebuggerConnection::DebuggerConnection(QString host, quint16 port)
{
	verify(connect(&m_timer, SIGNAL(timeout()), SLOT(run())));
	verify(connect(&m_socket, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(onSocketError(QAbstractSocket::SocketError))));
	verify(connect(&m_socket, SIGNAL(connected()), SLOT(onConnected())));
	verify(connect(&m_socket, SIGNAL(disconnected()), SLOT(onDisconnected())));

	m_socket.connectToHost(host, port);
}
///////////////////////////////////////////////////////////////////////////////////////////////////

DebuggerConnection::~DebuggerConnection()
{}
///////////////////////////////////////////////////////////////////////////////////////////////////




bool DebuggerConnection::isConnected() const
{
	return m_socket.isOpen() && m_controller != nullptr;
}
///////////////////////////////////////////////////////////////////////////////////////////////////

void DebuggerConnection::disconnect()
{
	m_socket.close();
}
///////////////////////////////////////////////////////////////////////////////////////////////////




void DebuggerConnection::run()
{
	if(m_controller)
	{
		m_controller->pull();
	}
}
///////////////////////////////////////////////////////////////////////////////////////////////////

void DebuggerConnection::onSocketError(QAbstractSocket::SocketError error)
{
	// When disconnected, we have to kill everything that works with the socket
	m_controller.reset();
	m_queue.reset();
	m_stream.reset();

	emit connection_error(error);
}
///////////////////////////////////////////////////////////////////////////////////////////////////

void DebuggerConnection::onConnected()
{
	// The connection has been established: We can now use the socket as a device
	// for our iostream:
	m_stream = boost::make_shared<iostream>(&m_socket);
	m_stream->setEndian(boostext::little_endian_ordering);

	// The queue can now be created that operates on the stream
	m_queue = duplex_queue::ptr(new duplex_queue(*m_stream));

	// And finally the controller that uses the queue to write commands and read responses
	m_controller = boost::make_shared<Engine::Debugger::Controller>(m_queue, m_queue);
}
///////////////////////////////////////////////////////////////////////////////////////////////////

void DebuggerConnection::onDisconnected()
{
	// When disconnected, we have to kill everything that works with the socket
	m_controller.reset();
	m_queue.reset();
	m_stream.reset();

	emit disconnected();
}
///////////////////////////////////////////////////////////////////////////////////////////////////
